package endcourseproject;

public class MCPS_dataRequest extends ZTCMsg {

	public static final byte AddrModeNone  = (byte)0;
	public static final byte AddrModeShort  = (byte)2;
	public static final byte AddrModeLong  = (byte)3;
	public static final byte[] DefaultPanId = {(byte)0xBE,(byte)0xBA};  
	public static final byte[] BroadcastAddr = {(byte)0xFF,(byte)0xFF};  

	
	public static final byte NwkMcpsOpcodeGroup = (byte)0x87;    // NWK_MCPS_SapHandler          
	// MCPS Opcode ID's
	public static final byte McpsDataReq = (byte)0x00;  // data request 
	
	public static final int dstAddrOffset = 0;   
	public static final int dstAddrLen = 8;   
	//private byte[] dstAddr;  // First 0/2/8 bytes is the address as defined by dstAddrMode
	public static final int dstPanIdOffset = dstAddrLen;   
	public static final int dstPanIdLen = 2;   
	//private byte[] dstPanId; // 16 bit word converted to little endian byte array
	public static final int dstAddrModeOffset = dstPanIdOffset + dstPanIdLen;   
	public static final int dstAddrModeLen = 1;   
	//byte dstAddrMode;
	public static final int srcAddrOffset = dstAddrModeOffset + dstAddrModeLen;   
	public static final int srcAddrLen = 8;   
	//private byte[] srcAddr;  // First 0/2/8 bytes is the address as defined by srcAddrMode
	public static final int srcPanIdOffset = srcAddrOffset + srcAddrLen;   
	public static final int srcPanIdLen = 2;   
	//private byte[] srcPanId; // 16 bit word converted to little endian byte array
	public static final int srcAddrModeOffset = srcPanIdOffset + srcPanIdLen;   
	public static final int srcAddrModeLen = 1;   
	//byte srcAddrMode;
	public static final int msduLengthOffset = srcAddrModeOffset + srcAddrModeLen;   
	public static final int msduLengthLen = 1;   
	//byte msduLength;  // 0-102
	public static final int msduHandleOffset = msduLengthOffset + msduLengthLen;   
	public static final int msduHandleLen = 1;   
	//byte msduHandle; 
	public static final int txOptionsOffset = msduHandleOffset + msduHandleLen;   
	public static final int txOptionsLen = 1;   
	//byte txOptions;
	public static final int msduOffset = txOptionsOffset + txOptionsLen;   
	public static final int msduLen = 1;   
	//private byte[] msdu;     
	
	public MCPS_dataRequest(byte[] dstAddr,byte[] srcAddr,byte msduLength, byte[] msdu)
	{
		super(NwkMcpsOpcodeGroup, McpsDataReq, msduOffset+msduLength, new byte[msduOffset+msduLength]);
		setDstAddr(dstAddr);
		setDstPanId(DefaultPanId);
		setSrcAddr(srcAddr);
		setSrcPanId(DefaultPanId);
		setMsduLength(msduLength);
		setMsdu(msdu);
		setMsduHandle((byte)42); // just a value - don't care
		setTxOptions((byte)0);   // no security and no Mac Acknowledge 
		
	}

	/**
	 * @return the dstAddr
	 */
	public byte[] getDstAddr() {
		byte[] dstAddr = new byte[dstAddrLen];
		System.arraycopy( this.getData(), dstAddrOffset,dstAddr, 0, dstAddr.length);
		return dstAddr;
	}

	/**
	 * @param dstAddr the dstAddr to set
	 */
	public void setDstAddr(byte[] dstAddr) {
        if (dstAddr == null)
        {
        	setDstAddrMode(AddrModeNone);
        	return;
        }		
        else if (dstAddr.length == dstAddrLen)
        {
        	setDstAddrMode(AddrModeLong);
        }
        else if (dstAddr.length == 2)
        {
        	setDstAddrMode(AddrModeShort);
        }
		System.arraycopy( dstAddr, 0,this.getData(), dstAddrOffset, dstAddr.length);
	}

	/**
	 * @return the dstPanId
	 */
	public byte[] getDstPanId() {
		byte[] dstPanId = new byte[dstPanIdLen];
		System.arraycopy( this.getData(), dstPanIdOffset,dstPanId, 0, dstPanId.length);
		return dstPanId;
	}

	/**
	 * @param dstPanId the dstPanId to set
	 */
	public void setDstPanId(byte[] dstPanId) {
		if (dstPanId != null){			
			System.arraycopy( dstPanId, 0,this.getData(), dstPanIdOffset, dstPanId.length);
		}
	}

	/**
	 * @return the dstAddrMode
	 */
	public byte getDstAddrMode() {
		return this.getData()[dstAddrModeOffset];
	}

	/**
	 * @param dstAddrMode the dstAddrMode to set
	 */
	public void setDstAddrMode(byte dstAddrMode) {
		this.getData()[dstAddrModeOffset] = dstAddrMode;
	}

	/**
	 * @return the srcAddr
	 */
	public byte[] getSrcAddr() {
		byte[] srcAddr = new byte[srcAddrLen];
		System.arraycopy( this.getData(), srcAddrOffset,srcAddr, 0, srcAddr.length);
		return srcAddr;
	}

	/**
	 * @param srcAddr the srcAddr to set
	 */
	public void setSrcAddr(byte[] srcAddr) {
        if (srcAddr == null)
        {
        	setSrcAddrMode(AddrModeNone);
        	return;
        }		
        else if (srcAddr.length == dstAddrLen)
        {
        	setSrcAddrMode(AddrModeLong);
        }
        else if (srcAddr.length == 2)
        {
        	setSrcAddrMode(AddrModeShort);
        }
		System.arraycopy( srcAddr, 0,this.getData(), srcAddrOffset, srcAddr.length);
	}

	/**
	 * @return the srcPanId
	 */
	public byte[] getSrcPanId() {
		byte[] srcPanId = new byte[srcPanIdLen];
		System.arraycopy( this.getData(), srcPanIdOffset,srcPanId, 0, srcPanId.length);
		return srcPanId;
	}

	/**
	 * @param srcPanId the srcPanId to set
	 */
	public void setSrcPanId(byte[] srcPanId) {
		if (srcPanId != null){			
		System.arraycopy( srcPanId, 0,this.getData(), srcPanIdOffset, srcPanId.length);
		}
	}

	/**
	 * @return the srcAddrMode
	 */
	public byte getSrcAddrMode() {
		return this.getData()[srcAddrModeOffset];
	}

	/**
	 * @param srcAddrMode the srcAddrMode to set
	 */
	public void setSrcAddrMode(byte srcAddrMode) {
		this.getData()[srcAddrModeOffset] = srcAddrMode;
	}

	/**
	 * @return the msduLength
	 */
	public byte getMsduLength() {
		return this.getData()[msduLengthOffset];
	}

	/**
	 * @param msduLength the msduLength to set
	 */
	public void setMsduLength(byte msduLength) {
		this.getData()[msduLengthOffset] = msduLength;
	}

	/**
	 * @return the msduHandle
	 */
	public byte getMsduHandle() {
		return this.getData()[msduHandleOffset];
	}

	/**
	 * @param msduHandle the msduHandle to set
	 */
	public void setMsduHandle(byte msduHandle) {
		this.getData()[msduHandleOffset] = msduHandle;
	}

	/**
	 * @return the txOptions
	 */
	public byte getTxOptions() {
		return this.getData()[txOptionsOffset];
	}

	/**
	 * @param txOptions the txOptions to set
	 */
	public void setTxOptions(byte txOptions) {
		this.getData()[txOptionsOffset] = txOptions;
	}

	/**
	 * @return the msdu
	 */
	public byte[] getMsdu() {
		byte[] msdu = new byte[getMsduLength()];
		System.arraycopy( this.getData(), msduOffset,msdu, 0, getMsduLength());
		return msdu;
	}

	/**
	 * @param msdu the msdu to set
	 */
	public void setMsdu(byte[] msdu) {
		if(msdu != null)
		{
			setMsduLength((byte) msdu.length);
			System.arraycopy( msdu, 0,this.getData(), msduOffset, msdu.length);
		}
		else
		{
			setMsduLength((byte) 0);
		}
	}

}
